﻿using System.Linq;
using System.Windows.Documents;

using VSTalk.Engine.Core.Context;
using VSTalk.Engine.Core.Feed;
using VSTalk.Engine.ViewModel.Messenger.ThreadRenderer.BlockBuilder;
using VSTalk.Engine.ViewModel.Messenger.ThreadRenderer.Model;

namespace VSTalk.Engine.ViewModel.Messenger.ThreadRenderer.Command
{
    public class RenderHistoryMessage : BaseRenderingCommand
    {
        private IMessage _message;

        private ContentBlockBuilder _contentBlockBuilder;
        private SubjectBlockBuilder _subjectBlockBuilder;

        public IModelContext ModelContext
        {
            get { return AppServices.Get<IModelContext>(); }
        }

        public RenderHistoryMessage(ConversationModel conversationModel, IMessage message)
                : base(conversationModel)
        {
            _message = message;

            var client = ModelContext.GetClientById(message.ClientId);
            
            _contentBlockBuilder = new ContentBlockBuilder(client);
            _subjectBlockBuilder = new SubjectBlockBuilder(client);
        }

        public override void Execute()
        {
            if (!string.IsNullOrEmpty(_message.XmppMessage.Subject))
            {
                RenderSubject();
            }
            if (!string.IsNullOrEmpty(_message.XmppMessage.Body))
            {
                RenderContent();
            }
        }

        private void RenderSubject()
        {
            var messageSection = GetOrAddMessageSection();
            var block = _subjectBlockBuilder.CreateBlock(_message);
            var first = messageSection.Blocks.FirstBlock;
            if (first != null)
            {
                messageSection.Blocks.InsertBefore(first, block);
            }
            else
            {
                messageSection.Blocks.Add(block);
            }
        }

        private void RenderContent()
        {
            var messageSection = GetOrAddMessageSection();
            var block = _contentBlockBuilder.CreateBlock(_message);
            var first = messageSection.Blocks.FirstBlock;
            if (first != null)
            {
                messageSection.Blocks.InsertBefore(first, block);
            }
            else
            {
                messageSection.Blocks.Add(block);
            }
        }

        private Section GetOrAddMessageSection()
        {
            var target = ConversationModel.Sections
                    .FirstOrDefault(conversationSection => conversationSection.Type == SectionType.Message);
            if (target != null)
            {
                return target.Content;
            }

            var newSection = new ConversationSection
            {
                Content = new Section(),
                Type = SectionType.Message
            };
            ConversationModel.AddFirst(newSection);
            return newSection.Content;
        }
    }
}